package com.leetcode.basic.synchronize;

import org.junit.Test;

public class SynMethod {

	@Test
	public void test() throws Exception {
		Obj obj = new Obj();

		new Thread(() -> {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			obj.b();
		}).start();

		obj.a();

		// a()完成后，才能执行b()
	}

	@Test
	public void test2() throws Exception {
		Obj obj = new Obj();

		new Thread(() -> {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			obj.b();
		}).start();

		obj.a2();

		// 非同步a2()执行，不影响b()执行.
	}

	@Test
	public void test3() throws Exception {
		Obj obj = new Obj();

		new Thread(() -> {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			obj.b();
		}).start();

		obj.a3();

		// 块同步a3()执行，不影响 同步b() 执行.
	}

	@Test
	public void test4() throws Exception {
		Obj obj = new Obj();

		new Thread(() -> {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			obj.b2();
		}).start();

		obj.a3();

		// 块同步a3()执行，影响块同步b2()执行.
	}

	private class Obj {

		synchronized void a() throws InterruptedException {
			System.out.println("A");
			Thread.sleep(1000);
			System.out.println("A 完成");
		}

		void a2() throws InterruptedException {
			System.out.println("A2");
			Thread.sleep(1000);
			System.out.println("A2 完成");
		}

		void a3() throws InterruptedException {
			synchronized (Obj.class) {
				System.out.println("A3");
				Thread.sleep(1000);
				System.out.println("A3 完成");
			}
		}

		synchronized void b() {
			System.out.println("B");
		}

		synchronized void b2() {
			synchronized (Obj.class) {
				System.out.println("B2");
			}
		}
	}
}
